home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Languages Suite
/
ProgramD2.iso
/
Borland
/
Borland Pascal with Objects 7.0
/
WHEREIS.ZIP
/
IMACROS.MAC
< prev
next >
Wrap
Text File
|
1992-10-27
|
9KB
|
319 lines
; FILENAME: IMACROS.MAC
;
; Copyright (c) 1988, 1989 by Borland International, Inc.
;
; DESCRIPTION: This include file implements miscellaneous useful macros.
; The file uses ideal mode syntax.
;
; ASSEMBLY INSTRUCTIONS: If assembling modules for 286/386 processors,
; turn on the P286 directive in order to take advantage of 286/386 specific
; instructions. I.E.
;
; TASM filename /jP286
;
; NOTE: In order to use this macro file you must also include the macro file
; IBIOS.MAC in your module.
;
; The macros implemented in this file are:
; Name Function
; --------------- ---------------------------------------------------
; FarPtrAddress Calculate the absolute address of a 32-bit pointer
; CompareFarPointers Compare two 32-bit pointers
; MakePascalString Allocate a string using Turbo Pascal format
; InitStack Initialize the stack registers for parameter access
; RestoreStack Restore the stack registers
; GetVideoAddress Determine the segment address of video ram
; DosCall Performs the DOS int 21h call
; LoadSegment Loads a segment register with a value
; Beep Sounds the speaker
; The following macro calculates the absolute address of the far pointer
; passed to it.
;
; Input
; Segment:Ofs - Far pointer
; Output
; dx:ax - Absolute address of pointer(20 bits)
; Calling convention
; NA
; Registers modified
; ax, bx, cx, dx, Flags
macro FarPtrAddress Segment, Ofs
ifb <Segment>
display "Segment parameter must be provided in call to FarPtrAddress"
err
endif
ifb <Ofs>
display "Ofs parameter must be provided in call to FarPtrAddress"
err
endif
mov bx, Segment ; Calculate the low 12 bits
and bx, 0FFFh
if (@Cpu and 100b) eq 100b ; Shift the segment value right 12 bits
shl bx, 4 ; to prepare for addition
else
mov cl, 4
shl bx, cl
endif
mov dx, Segment
if (@Cpu and 100b) eq 100b ; Shift the segment value right 12 bits
shr dx, 12 ; to prepare for addition
else
mov cl, 12
shr dx, cl
endif
mov ax, Ofs ; Determine the low 16 bits of the 20-bit
add ax, bx ; address
adc dx, 0 ; Calculate the absolute segment
endm
; The following macros compares two far pointers to determine their
; relative absolute addresses.
;
; Input
; Seg1:Ofs1 - Far pointer
; Seg2:Ofs2 - Far pointer
; Output
; The Flags register is set by the CMP instruction.
; Calling convention
; NA
; Registers modified
; ax, bx, cx, dx, Flags
macro CompareFarPointers Seg1, Ofs1, Seg2, Ofs2
local Exit, SegmentsEqual
ifb <Seg1>
display "Need to declare Seg1 in call to CompareFarPointers"
err
endif
ifb <Seg2>
display "Need to declare Seg2 in call to CompareFarPointers"
err
endif
ifb <Ofs1>
display "Need to declare Ofs1 in call to CompareFarPointers"
err
endif
ifb <Ofs2>
display "Need to declare Ofs2 in call to CompareFarPointers"
err
endif
mov ax, Seg1 ; Load segment registers
mov dx, Seg2
cmp ax, dx ; Check if segment registers are equal
je short SegmentsEqual
; If the segments aren't equal we have to calculate the absolute
; addresses of the pointers
FarPtrAddress Seg1, Ofs1 ; Calculate absolute adress of Seg1:Ofs1
push dx ; Store calculated values on the stack
push ax
FarPtrAddress Seg2, Ofs2 ; Calculate absolute adress of Seg2:Ofs2
mov bx, sp
cmp [ss:bx+2], dx ; Compare absolute segment adresses
pop bx ; Clean up the stack
pop bx
jne short Exit ; If they aren't equal we're done
cmp [ss:bx], ax ; Check absolute offsets
jmp short Exit
SegmentsEqual:
cmp Ofs1, Ofs2 ; Compare offsets
Exit:
endm
; The following macro builds strings using Turbo Pascal conventions. That
; is, the string is stored with a preceding 'length byte.' This macro is
; an excellent example of the clever things that can be done using the
; ORG directive.
;
; Input
; Id - Label to associate with the string
; Msg - Contents of the string
; Output
; none
; Calling convention
; NA
; Registers modified
; none
macro MakePascalString Id, Msg
local MsgLen, EndStr
ifb <Id>
display "Must pass name of string to MakePascalString"
err
else
ifb <Msg>
display "Must pass string parameter to MakePascalString
err
else
Id db EndStr - Id - 1, &Msg& ; Allocate space for the string
label EndStr byte ; a preceding byte storing the
endif ; length of the string.
endif
endm
; The following macro initializes bp and sp in preparation for access
; of parameters passed to a routine on the stack. The parameter LocalVars
; is optional and if provided indicates the amount of space that should
; be reserved for local variables. LocalVars must be an even value.
;
; Input
; LocalVars - # of bytes to reserve for local variables
; Output
; none
; Calling convention
; NA
; Registers modified
; bp, sp
macro InitStack LocalVars
push bp ; Set up the stack for a sub-routine
mov bp, sp
ifnb <LocalVars>
sub sp, LocalVars ; Make space for local variables
endif
endm
; The following macro restores bp and sp after a routine is finished
; accessing parameters passed to a routine on the stack. The parameter
; LocalVars is optional and if provided indicates the amount of space
; that was reserved for local variables. LocalVars must be an even value.
;
; Input
; LocalVars - # of bytes that were reserved for local variables
; Output
; none
; Calling convention
; NA
; Registers modified
; bp, sp
macro RestoreStack LocalVars
ifnb <LocalVars>
add sp, LocalVars
endif ; ifnb <LocalVars>
pop bp
endm ; InitStack
; The following macro returns the current segment address of video ram.
;
; Input
; none
; Output
; ax
; Calling convention
; NA
; Registers modified
; ax, bx, Flags
macro GetVideoAddress
local Color, Exit
GetVideoMode
cmp al, 07h
jne short Color
mov ax, 0B000h ;; It's a monochrome card
jmp short Exit
Color:
mov ax, 0B800h ;; It's a color card
Exit:
endm
; The following macro performs the Int 21h call to execute DOS's
; services.
;
; Input
; Service - Service # to execute
; Output
; None
; Calling convention
; NA
; Registers modified
; NA
macro DosCall Service
ifb <Service>
display "The Service parameter must be provided to DosCall
err
endif
mov ah, Service
int DOS_FUNCTION
endm
; The following macro loads a segment register with a value. The macro
; attempts to do all possible checks to determine the type of the value
; being moved into the segment register. Based on this information it
; generates the correct code.
;
; Input
; Segm - Segm register to load value into
; Value - Value to put on the stack
; Output
; none
; Calling convention
; NA
; Registers modified
; ax
macro LoadSegment Segm, Value
local IsSegReg
macro CheckRegisterName Register
IsSegReg = 0
if (symtype Register) eq 110000b
irp Reg, <es, ds, cs, ss, fs, gs>
ifidni <Register>, <&Reg&>
IsSegReg = 1 ; Return that the register
exitm ; is a segment register
endif
endm
endif
endm
CheckRegisterName <Value> ; Check if the value to be
if IsSegReg ; loaded into the segment
push Value ; register is itself a
pop Segm ; segment register.
else
if (symtype Segm eq 24h) or (symtype Segm eq 0h) ; Parameter is a constant
mov ax, Value
mov Segm, ax
else
mov Segm, Value ; Value is a memory reference
endif
endif
endm
; The following macro generates a beep by displaying the ASCII Bell
; character.
;
; Input
; none
; Output
; none
; Calling convention
; NA
; Registers modified
; ax, dl
macro Beep
mov dl, BELL
DosCall DOS_CHARACTER_OUTPUT
endm